package com.chuangke.common.utils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class DataUtils {

    /**
     * 比较两个对象不同的属性并判断是否有修改
     *
     * @param oldObj           旧对象
     * @param newObj           新对象
     * @param ignoreProperties 可忽略对比的属性
     * @return boolean
     */
    public static <T> boolean isDataValueModifyed(T oldObj, T newObj, String... ignoreProperties){
        List<ModifiedPropertyInfo> list = getDifferentProperty(oldObj,newObj,ignoreProperties) ;
        return !list.isEmpty() ;
    }

    /**
     * 比较两个对象不同的属性并记录返回
     *
     * @param oldObj           旧对象
     * @param newObj           新对象
     * @param ignoreProperties 可忽略对比的属性
     * @return java.util.List<com.sdyy.staff.utils.ModifiedPropertyInfo>
     */
    public static <T> List<ModifiedPropertyInfo> getDifferentProperty(T oldObj, T newObj, String... ignoreProperties) {
        if (oldObj == null || newObj == null) {
            return Collections.emptyList();
        }

        Map<String, Object> oldPropertyValueMap = getObjectPropertyValue(oldObj, ignoreProperties) ;
        Map<String, Object> newPropertyValueMap = getObjectPropertyValue(newObj, ignoreProperties) ;

        List<ModifiedPropertyInfo> modifiedPropertyInfos = new ArrayList<>();

        for(String property : oldPropertyValueMap.keySet()){
            Object oldValue = oldPropertyValueMap.get(property);
            Object newValue = newPropertyValueMap.get(property);

            if(oldValue == null && newValue == null){
                continue;
            }

            if((oldValue!=null && newValue== null) || (oldValue==null && newValue!= null) || !oldValue.equals(newValue)){
                ModifiedPropertyInfo modifiedPropertyInfo = new ModifiedPropertyInfo();
                modifiedPropertyInfo.setPropertyName(property);
                modifiedPropertyInfo.setOldValue(oldValue);
                modifiedPropertyInfo.setNewValue(newValue);
                modifiedPropertyInfos.add(modifiedPropertyInfo);
            }
        }
        return modifiedPropertyInfos;
    }


    /**
     * 通过反射获取对象的属性名称、getter返回值类型、属性值等信息
     *
     * @param obj              对象
     * @param ignoreProperties 可忽略比对的属性
     * @return java.util.List<com.sdyy.staff.utils.PropertyModelInfo>
     */
    public static <T> Map<String, Object> getObjectPropertyValue(T obj, String... ignoreProperties) {
        Map<String, Object> map = new HashMap<>();

        List<Field> fields = ReflectionUtils.getAllField(obj) ;//.getDeclaredFields();
        List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);
        for (Field field : fields) {
            if (ignoreList.contains(field.getName())) {
                continue;
            }

            field.setAccessible(true);
            try {
                map.put(field.getName(), field.get(obj));
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
        return map;
    }

}
